﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Dycox.ComponentModel
{
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public class ModelPropertyAttribute : Attribute
    {
        public ModelPropertyAttribute(ModelPropertyUsage usage)
        {
            _usage = usage;
            _canModify = (usage == ModelPropertyUsage.User || usage == ModelPropertyUsage.Application);
        }

        public ModelPropertyAttribute(ModelPropertyUsage usage, bool canModify)
            : this(usage)
        {
            if (canModify && !_canModify)
                throw new ArgumentException("Cannot set CanModify to true when usage is " + usage);

            _usage = usage;
            _canModify = canModify;
        }

        private readonly ModelPropertyUsage _usage;

        public ModelPropertyUsage Usage
        {
            get { return _usage; }
        }

        private readonly bool _canModify;

        public bool CanModify
        {
            get { return _canModify; }
        }


        public static readonly ModelPropertyAttribute Key = new ModelPropertyAttribute(ModelPropertyUsage.Key);

        public static readonly ModelPropertyAttribute Application = new ModelPropertyAttribute(ModelPropertyUsage.Application);

        public static readonly ModelPropertyAttribute User = new ModelPropertyAttribute(ModelPropertyUsage.User);

        public static readonly ModelPropertyAttribute Control = new ModelPropertyAttribute(ModelPropertyUsage.Control);

        public static readonly ModelPropertyAttribute Any = new ModelPropertyAttribute(ModelPropertyUsage.Application);

        public static ModelPropertyAttribute GetInstance(ModelPropertyUsage usage)
        {
            switch (usage)
            {
                case ModelPropertyUsage.User:
                    return User;
                case ModelPropertyUsage.Key:
                    return Key;
                case ModelPropertyUsage.Application:
                    return Application;
                case ModelPropertyUsage.Control:
                    return Control;
                default:
                    throw new ArgumentException(SR.GetString("invalid_enum_member", usage, typeof(ModelPropertyUsage)));
            }
        }

        // override object.Equals
        public override bool Equals(object obj)
        {
            ModelPropertyAttribute other = obj as ModelPropertyAttribute;

            if (other != null)
            {
                if (object.ReferenceEquals(this, Any) || object.ReferenceEquals(other, Any))
                    return true;

                return other._usage == this._usage;
            }
            else
                return false;
        }

        // override object.GetHashCode
        public override int GetHashCode()
        {
            return _usage.GetHashCode();
        }
    }
}
